<script lang="ts" setup>
import { useUserStore } from '@/stores/user'
import { io, type Socket } from 'socket.io-client'
// 引入聊天室状态组件
import roomStatus from './components/room-status.vue'
import { ref } from 'vue';
import type { OrderDetail } from '@/types/consult';
import { orderDetailApi, uploadImgApi } from '@/apis/consult';
import type { MsgData, MsgItem } from '@/types/room';
import patientInfo from './components/patient-info.vue'
import notifyInfo from './components/notify-info.vue'
import messageInfo from './components/message-info.vue'
import prescriptionInfo from './components/prescription-info.vue';
import { nextTick } from 'vue';

const store = useUserStore()
const props = defineProps<{
  orderId: string
  payResult: string
}>()

// 所有的消息数组
const messageList = ref<MsgItem[]>([])

// 1. 如果支付失败, 拦截去个人中心
if (props.payResult === 'false') {
  uni.switchTab({
    url: '/pages/my/index'
  })
}

// 2. 建立socket.io的连接
const socket: Socket = io('https://consult-api.itheima.net', {
  auth: { token: 'Bearer ' + store.user.token },
  query: { orderId: props.orderId },
  transports: ['websocket', 'polling'],
  timeout: 5000,
})

socket.on('connect', () => {
  console.log('连接建立成功');
})

socket.on('error', (err) => {
  console.log('连接出现问题', err);
})

socket.on('disconnect', () => {
  console.log('断开连接');
})

// 3. 根据订单id获取订单详情
const orderDetail = ref<OrderDetail>({} as OrderDetail)
const getOrderDetail = async () => {
  if (!props.orderId) return uni.showToast({ title: '订单id不存在' })
  const res = await orderDetailApi(props.orderId)
  orderDetail.value = res
  // console.log(orderDetail.value)
}
getOrderDetail()
// 监听订单状态的变化
socket.on('statusChange', getOrderDetail)


// 4. 获取默认消息
socket.on('chatMsgList', (res: MsgData) => {
  // 4.1 判断
  if (res.code !== 10000) return uni.showToast({ title: '获取历史消息失败' })
  console.log(res.data)
  // 4.2 处理消息分组中的数据放入数组
  res.data?.forEach(item => {
    messageList.value.push({
      id: item.createTime,
      msgType: 31,
      msg: {
        content: item.createTime
      }
    }, ...item.items!)
  })
  // console.log(messageList.value)
})

// 5. 接收医生发送的消息
socket.on('receiveChatMsg', (msg: MsgItem) => {
  console.log(msg)

  // 5.1 标明消息已读
  socket.emit('updateMsgStatus', msg.id)
  // 5.2 把消息追加到消息数组
  messageList.value.push(msg)

  // 5.3 让滚动视图滚动到最后
  // vue中数据驱动视图, 数据是同步更新, 视图是异步更新
  // 数据更新了视图也更新了 就会触发nextTick函数的执行
  nextTick(() => {
    sp.value = 'item' + (messageList.value.length - 1)
  })
})

// 6. 发送文字消息给服务器
const textMessage = ref('')
const onConfirm = () => {
  // console.log(textMessage.value);
  // 6.1 判断是否有文字
  if (textMessage.value.trim() === '') return uni.showToast({ title: '不能发送空消息', icon: 'none' })

  // 6.2 把文字包装成一条消息发给服务器
  socket.emit('sendChatMsg', {
    from: store.user.id,
    to: orderDetail.value.docInfo?.id,
    msgType: 1,
    msg: {
      content: textMessage.value
    }
  })

  // 6.3 清空输入框
  textMessage.value = ''
}

// 7. 发送图片消息
const onSendImg = async () => {
  // 7.1 判断医生的状态
  if (orderDetail.value.status !== 3) {
    return uni.showToast({ title: '当前医生不在接诊状态', icon: 'none' })
  }

  // 7.2 获取图片文件完成上传得到图片的url地址
  const temp = await uni.chooseImage({
    sizeType: ['original', 'compressed'],
    sourceType: ['album', 'camera'],
  })
  const res = await uploadImgApi(temp.tempFilePaths[0])


  // 7.3 把图片的Url包装成一个图片消息发给服务器
  socket.emit('sendChatMsg', {
    from: store.user.id,
    to: orderDetail.value.docInfo?.id,
    msgType: 4,
    msg: {
      picture: res
    }
  })
}

// 8. 滚动到最底部
const sp = ref('')

</script>

<template>
  <view class="room-page">
    <!-- 聊天室状态组件 -->
    <room-status v-if="orderDetail.id" :status="orderDetail.status" :status-value="orderDetail.statusValue"
      :countdown="orderDetail.countdown" />

    <scroll-view refresher-enabled refresher-background="#f2f2f2" scroll-y style="flex: 1; overflow: hidden"
      :scroll-into-view="sp">
      <!-- <view > -->
      <!-- 此处将来填充更多代码... -->
      <view class="message-container" v-for="(item, index) in messageList" :key="item.id" :id="`item${index}`">
        <!-- 患者病情消息 -->
        <patient-info :info="item.msg?.consultRecord!" v-if="item.msgType === 21" />
        <!-- 通知消息 -->
        <notify-info v-if="item.msgType! >= 31" :msg-type="item.msgType!">
          {{ item.msg?.content }}
        </notify-info>
        <!-- 文字和图片消息 -->
        <message-info v-if="item.msgType! <= 4" :info="item" :type="item.msgType!" />
        <!-- 处方消息 -->
        <prescription-info v-if="item.msgType === 22" :info="item.msg?.prescription!" />
      </view>
      <!-- </view> -->
    </scroll-view>

    <!-- 发送消息 -->
    <view class="message-bar">
      <template v-if="true">
        <uni-easyinput v-model="textMessage" :disabled="orderDetail.status !== 3" :clearable="false"
          :input-border="false" placeholder-style="font-size: 32rpx; color: #c3c3c5;" placeholder="问医生"
          @confirm="onConfirm" />
        <view class="image-button">
          <uni-icons size="40" color="#979797" type="image" @click="onSendImg"></uni-icons>
        </view>
      </template>
      <button v-else class="uni-button">咨询其它医生</button>
    </view>
  </view>
</template>

<style lang="scss">
@import './index.scss';
</style>